#ifndef CSV_OUTPUT_H_
#define CSV_OUTPUT_H_
#include "minicsv.h"
#include "Order.h"
#include "Trade.h"
#include "InvestorPosition.h"
#include "TradingAccount.h"


inline mini::csv::ifstream& operator >> (mini::csv::ifstream& ar, TradingAccount& ioa)
{
	ar >> ioa.AccountID
		>> ioa.BrokerID
		>> ioa.TradingDay
		>> ioa.UpdateTime
		>> ioa.PreBalance
		>> ioa.Commission
		>> ioa.CurrMargin
		>> ioa.CloseProfit
		>> ioa.PositionProfit
		>> ioa.Available
		>> ioa.Deposit
		>> ioa.Withdraw
		>> ioa.CurrencyID;
	return ar;
}


inline mini::csv::ofstream& operator << (mini::csv::ofstream& ar, const TradingAccount& ioa)
{
	ar << ioa.AccountID
		<< ioa.BrokerID
		<< ioa.TradingDay
		<< ioa.UpdateTime
		<< ioa.PreBalance
		<< ioa.Commission
		<< ioa.CurrMargin
		<< ioa.CloseProfit
		<< ioa.PositionProfit
		<< ioa.Available
		<< ioa.Deposit
		<< ioa.Withdraw
		<< ioa.CurrencyID;
	return ar;
}


inline mini::csv::ifstream& operator >> (mini::csv::ifstream& ar, InputOrderAction& ioa)
{
	ar >> ioa.BrokerID
		>> ioa.InvestorID
		>> ioa.OrderActionRef
		>> ioa.OrderRef
		>> ioa.RequestID
		>> ioa.FrontID
		>> ioa.SessionID
		>> ioa.ExchangeID
		>> ioa.OrderSysID
		>> (char&)ioa.ActionFlag
		>> ioa.InstrumentID;
	return ar;
}

	template<>
	inline mini::csv::ofstream& operator << (mini::csv::ofstream& ar, const InputOrderAction& ioa)
	{
		ar << ioa.BrokerID
			<< ioa.InvestorID
			<< ioa.OrderActionRef
			<< ioa.OrderRef
			<< ioa.RequestID
			<< ioa.FrontID
			<< ioa.SessionID
			<< ioa.ExchangeID
			<< ioa.OrderSysID
			<< (char&)ioa.ActionFlag
			<< ioa.InstrumentID;
		return ar;
	}

	template<>
	inline mini::csv::ifstream& operator >> (mini::csv::ifstream& ar, struct InputOrder& io)
	{
		ar >> io.BrokerID;
		ar >> io.InvestorID;
		ar >> io.InstrumentID;
		ar >> io.OrderRef;
		ar >> io.UserID;
		ar >> (char&)io.OrderPriceType;
		ar >> (char&)io.Direction;
		ar >> (char&)io.CombOffsetFlag[0] >> (char&)io.CombOffsetFlag[1] >> (char&)io.CombOffsetFlag[2]
			>> (char&)io.CombOffsetFlag[3] >> (char&)io.CombOffsetFlag[4];

		ar >> (char&)io.CombHedgeFlag[0] >> (char&)io.CombHedgeFlag[1] >> (char&)io.CombHedgeFlag[2]
			>> (char&)io.CombHedgeFlag[3] >> (char&)io.CombHedgeFlag[4];

		ar >> io.LimitPrice;
		ar >> io.VolumeTotalOriginal;
		ar >> io.TimeCondition;
		ar >> io.GTDDate;
		ar >> io.MinVolume;
		ar >> io.ContingentCondition;
		ar >> io.StopPrice;
		ar >> io.RequestID;
		ar >> io.FrontID;
		ar >> io.SessionID;
		ar >> io.OrderSysID;
		ar >> io.ExchangeID;
		return ar;
	}

	template<>
	inline mini::csv::ofstream& operator << (mini::csv::ofstream& ar, const InputOrder& io)
	{
		ar << io.BrokerID;
		ar << io.InvestorID;
		ar << io.InstrumentID;
		ar << io.OrderRef;
		ar << io.UserID;
		ar << io.OrderPriceType;
		ar << io.Direction;
		ar << io.CombOffsetFlag[0] << io.CombOffsetFlag[1] << io.CombOffsetFlag[2]
			<< io.CombOffsetFlag[3] << io.CombOffsetFlag[4];

		ar << io.CombHedgeFlag[0] << io.CombHedgeFlag[1] << io.CombHedgeFlag[2]
			<< io.CombHedgeFlag[3] << io.CombHedgeFlag[4];

		ar << io.LimitPrice;
		ar << io.VolumeTotalOriginal;
		ar << io.TimeCondition;
		ar << io.GTDDate;
		ar << io.MinVolume;
		ar << io.ContingentCondition;
		ar << io.StopPrice;
		ar << io.RequestID;
		ar << io.FrontID;
		ar << io.SessionID;
		ar << io.OrderSysID;
		ar << io.ExchangeID;
		return ar;
	}

	template<>
	inline mini::csv::ofstream& operator << (mini::csv::ofstream& ar, const Order& o)
	{
		ar << (InputOrder&)o;
		ar << o.ForceCloseReason;
		ar << o.IsAutoSuspend;
		ar << o.BusinessUnit;
		ar << o.OrderLocalID;
		ar << o.ParticipantID;
		ar << o.ClientID;
		ar << o.ExchangeInstID;
		ar << o.TraderID;
		ar << o.InstallID;
		ar << o.OrderSubmitStatus;
		ar << o.NotifySequence;
		ar << o.TradingDay;
		ar << o.SettlementID;
		ar << o.OrderSource;
		ar << o.OrderStatus;
		ar << o.OrderType;
		ar << o.VolumeTraded;
		ar << o.VolumeTotal;
		ar << o.InsertDate;
		ar << o.InsertTime;
		ar << o.ActiveTime;
		ar << o.SuspendTime;
		ar << o.UpdateTime;
		ar << o.CancelTime;
		ar << o.ActiveTraderID;
		ar << o.ClearingPartID;
		ar << o.SequenceNo;
		ar << o.UserProductInfo;
		ar << o.StatusMsg;
		ar << o.UserForceClose;
		ar << o.ActiveUserID;
		ar << o.BrokerOrderSeq;
		ar << o.RelativeOrderSysID;
		ar << o.ZCETotalTradedVolume;
		ar << o.IsSwapOrder;
		ar << o.SeatID;
		return ar;
	}


	template<>
	inline mini::csv::ofstream& operator << (mini::csv::ofstream& ar, const Trade& t)
	{
		ar << t.BrokerID;
		ar << t.InvestorID;
		ar << t.InstrumentID;
		ar << t.OrderRef;
		ar << t.UserID;
		ar << t.ExchangeID;
		ar << t.TradeID;
		ar << t.Direction;
		ar << t.OrderSysID;
		ar << t.ParticipantID;
		ar << t.ClientID;
		ar << t.TradingRole;
		ar << t.ExchangeInstID;
		ar << t.OffsetFlag;
		ar << t.HedgeFlag;
		ar << t.Price;
		ar << t.Volume;
		ar << t.TradeDate;
		ar << t.TradeTime;
		ar << t.TradeType;
		ar << t.PriceSource;
		ar << t.TraderID;
		ar << t.OrderLocalID;
		ar << t.ClearingPartID;
		ar << t.BusinessUnit;
		ar << t.SequenceNo;
		ar << t.TradingDay;
		ar << t.SettlementID;
		ar << t.BrokerOrderSeq;
		ar << t.TradeSource;
		ar << t.SeatID;
		return ar;
	}



	template<>
	inline mini::csv::ofstream& operator << (mini::csv::ofstream& ar, const InvestorPosition& ip)
	{
		ar << ip.InstrumentID;
		ar << ip.BrokerID;
		ar << ip.InvestorID;
		ar << ip.ExchangeID;
//		ar << ip.ClientID;
		ar << ip.OpenDate;
		ar << ip.PosiDirection;
		ar << ip.HedgeFlag;
		ar << ip.PositionDate;
		ar << ip.YdPosition;
		ar << ip.Position;
// 		ar << ip.LongFrozen;
// 		ar << ip.LongFrozenAmount;
// 		ar << ip.ShortFrozen;
// 		ar << ip.ShortFrozenAmount;
		ar << ip.OpenVolume;
		ar << ip.CloseVolume;
//		ar << ip.OpenAmount;
//		ar << ip.CloseAmount;
		ar << ip.PositionCost;
//		ar << ip.PreMargin;
		ar << ip.UseMargin;
// 		ar << ip.FrozenMargin;
// 		ar << ip.FrozenCash;
// 		ar << ip.FrozenCommission;
//		ar << ip.CashIn;
		ar << ip.Commission;
		ar << ip.CloseProfit;
		ar << ip.PositionProfit;
// 		ar << ip.PreSettlementPrice;
// 		ar << ip.SettlementPrice;
		ar << ip.TradingDay;
//		ar << ip.SettlementID;
		ar << ip.OpenCost;
//		ar << ip.ExchangeMargin;
// 		ar << ip.CombPosition;
// 		ar << ip.CombLongFrozen;
// 		ar << ip.CombShortFrozen;
// 		ar << ip.CloseProfitByDate;
// 		ar << ip.CloseProfitByTrade;
		ar << ip.TodayPosition;
// 		ar << ip.MarginRateByMoney;
// 		ar << ip.MarginRateByVolume;
// 		ar << ip.StrikeFrozen;
// 		ar << ip.StrikeFrozenAmount;
// 		ar << ip.AbandonFrozen;
		ar << ip.OpenPrice;
		return ar;
	}

	inline mini::csv::ifstream& operator >> (mini::csv::ifstream& ar, InvestorPosition& ip)
	{
		ar >> ip.InstrumentID;
		ar >> ip.BrokerID;
		ar >> ip.InvestorID;
		ar >> ip.ExchangeID;
		//		ar >> ip.ClientID;
		ar >> ip.OpenDate;
		ar >> (char&)ip.PosiDirection;
		ar >> (char&)ip.HedgeFlag;
		ar >> (char&)ip.PositionDate;
		ar >> ip.YdPosition;
		ar >> ip.Position;
		// 		ar >> ip.LongFrozen;
		// 		ar >> ip.LongFrozenAmount;
		// 		ar >> ip.ShortFrozen;
		// 		ar >> ip.ShortFrozenAmount;
		ar >> ip.OpenVolume;
		ar >> ip.CloseVolume;
		//		ar >> ip.OpenAmount;
		//		ar >> ip.CloseAmount;
		ar >> ip.PositionCost;
		//		ar >> ip.PreMargin;
		ar >> ip.UseMargin;
		// 		ar >> ip.FrozenMargin;
		// 		ar >> ip.FrozenCash;
		// 		ar >> ip.FrozenCommission;
		//		ar >> ip.CashIn;
		ar >> ip.Commission;
		ar >> ip.CloseProfit;
		ar >> ip.PositionProfit;
		// 		ar >> ip.PreSettlementPrice;
		// 		ar >> ip.SettlementPrice;
		ar >> ip.TradingDay;
		//		ar >> ip.SettlementID;
		ar >> ip.OpenCost;
		//		ar >> ip.ExchangeMargin;
		// 		ar >> ip.CombPosition;
		// 		ar >> ip.CombLongFrozen;
		// 		ar >> ip.CombShortFrozen;
		// 		ar >> ip.CloseProfitByDate;
		// 		ar >> ip.CloseProfitByTrade;
		ar >> ip.TodayPosition;
		// 		ar >> ip.MarginRateByMoney;
		// 		ar >> ip.MarginRateByVolume;
		// 		ar >> ip.StrikeFrozen;
		// 		ar >> ip.StrikeFrozenAmount;
		// 		ar >> ip.AbandonFrozen;
		ar >> ip.OpenPrice;
		return ar;
	}
	// 		template<class Archive>
	// 	inline void serialize(Archive& ar, InstrumentMarginRate& imr, const unsigned int version)
	// 	{
	// 		ar & imr.BrokerID;
	// 		ar & imr.HedgeFlag;
	// 		ar & imr.InstrumentID;
	// 		ar & imr.InvestorID;
	// 		ar & imr.InvestorRange;
	// 		ar & imr.IsRelative;
	// 		ar & imr.LongMarginRatioByMoney;
	// 		ar & imr.LongMarginRatioByVolume;
	// 		ar & imr.ShortMarginRatioByMoney;
	// 		ar & imr.ShortMarginRatioByVolume;
	// 	}
	// 
	// 
	// 		template<class Archive>
	// 	inline void serialize(Archive& ar, InstrumentCommisionRate& icr, const unsigned int version)
	// 	{
	// 		ar & icr.BrokerID;
	// 		ar & icr.CloseRatioByMoney;
	// 		ar & icr.CloseRatioByVolume;
	// 		ar & icr.CloseTodayRatioByMoney;
	// 		ar & icr.CloseTodayRatioByVolume;
	// 		ar & icr.InstrumentID;
	// 		ar & icr.InvestorID;
	// 		ar & icr.InvestorRange;
	// 		ar & icr.IsInitied;
	// 		ar & icr.OpenRatioByMoney;
	// 		ar & icr.OpenRatioByVolume;
	// 	}

#endif